
/* This file contains the terminal driver, both for the IBM console and regular
 * ASCII terminals.  It handles only the device-independent part of a TTY, the
 * device dependent parts are in console.c, rs232.c, etc.  This file contains
 * two main entry points, tty_task() and tty_wakeup(), and several minor entry
 * points for use by the device-dependent code.
 *
 * The device-independent part accepts "keyboard" input from the device-
 * dependent part, performs input processing (special key interpretation),
 * and sends the input to a process reading from the TTY.  Output to a TTY
 * is sent to the device-dependent code for output processing and "screen"
 * display.  Input processing is done by the device by calling 'in_process'
 * on the input characters, output processing may be done by the device itself
 * or by calling 'out_process'.  The TTY takes care of input queuing, the
 * device does the output queuing.  If a device receives an external signal,
 * like an interrupt, then it causes tty_wakeup() to be run by the CLOCK task
 * to, you guessed it, wake up the TTY to check if input or output can
 * continue.
 *
 * The valid messages and their parameters are:
 *
 *   HARD_INT:     output has been completed or input has arrived
 *   DEV_READ:     a process wants to read from a terminal
 *   DEV_WRITE:    a process wants to write on a terminal
 *   DEV_IOCTL:    a process wants to change a terminal's parameters
 *   DEV_OPEN:     a tty line has been opened
 *   DEV_CLOSE:    a tty line has been closed
 *   CANCEL:       terminate a previous incomplete system call immediately
 *
 *    m_type      TTY_LINE   PROC_NR    COUNT   TTY_SPEK  TTY_FLAGS  ADDRESS
 * ---------------------------------------------------------------------------
 * | HARD_INT    |         |         |         |         |         |         |
 * |-------------+---------+---------+---------+---------+---------+---------|
 * | DEV_READ    |minor dev| proc nr |  count  |         O_NONBLOCK| buf ptr |
 * |-------------+---------+---------+---------+---------+---------+---------|
 * | DEV_WRITE   |minor dev| proc nr |  count  |         |         | buf ptr |
 * |-------------+---------+---------+---------+---------+---------+---------|
 * | DEV_IOCTL   |minor dev| proc nr |func code|erase etc|  flags  |         |
 * |-------------+---------+---------+---------+---------+---------+---------|
 * | DEV_OPEN    |minor dev| proc nr | O_NOCTTY|         |         |         |
 * |-------------+---------+---------+---------+---------+---------+---------|
 * | DEV_CLOSE   |minor dev| proc nr |         |         |         |         |
 * |-------------+---------+---------+---------+---------+---------+---------|
 * | CANCEL      |minor dev| proc nr |         |         |         |         |
 * ---------------------------------------------------------------------------
 */

#include "kernel.h"
#include <termios.h>
#if ENABLE_SRCCOMPAT || ENABLE_BINCOMPAT
#include <sgtty.h>
#endif
#include <sys/ioctl.h>
#include <signal.h>
#include <minix/callnr.h>
#include <minix/com.h>
#include <mouse/mouse.h>	/* line 57 */
#if (CHIP == INTEL)
#include <minix/keymap.h>
#endif
#include "tty.h"
#include "proc.h"
#include "proto.h"		/* line 63 */

	...

FORWARD _PROTOTYPE( void mouse_interruption, (void)			);
FORWARD _PROTOTYPE( void dec_current_console, (void)			);
FORWARD _PROTOTYPE( void inc_current_console, (void)			);
FORWARD _PROTOTYPE( void print_tty, (struct tty *tp, char * s)		);

	...

PRIVATE tty_t *current_mouse_tty = FIRST_TTY;
PRIVATE int current_mouse_console = 0;

/*===========================================================================*
 *				tty_task				     *
 *===========================================================================*/
PUBLIC void tty_task()
{
/* Main routine of the terminal task. */

  message tty_mess;		/* buffer for all incoming messages */
  message mouse_mess;
  register tty_t *tp;
  unsigned line;

  /* Initialize the terminal lines. */
  for (tp = FIRST_TTY; tp < END_TTY; tp++) tty_init(tp);

  /* Display the Minix startup banner. */
  printf("Minix %s.%s  Copyright 1997 Prentice-Hall, Inc.\n\n",
						OS_RELEASE, OS_VERSION);

  printf("\nTRABAJO PRACTICO ESPECIAL DE SISTEMAS OPERATIVOS\n");
  printf("\t\tMOUSE DRIVER\n\n\n");

#if (CHIP == INTEL)
  /* Real mode, or 16/32-bit protected mode? */
#if _WORD_SIZE == 4
  printf("Executing in 32-bit protected mode\n\n");
#else
  printf("Executing in %s mode\n\n",
	protected_mode ? "16-bit protected" : "real");
#endif
#endif

  while (TRUE) {
	/* Handle any events on any of the ttys. */
	for (tp = FIRST_TTY; tp < END_TTY; tp++) {
		if (tp->tty_events) handle_events(tp);
	}

	receive(ANY, &tty_mess);

	/* A hardware interrupt is an invitation to check for events. */
	if (tty_mess.m_type == HARD_INT)
	{
		mouse_interruption();	/* line 182 */
		continue;
	}

	/* Check the minor device number. */
	line = tty_mess.TTY_LINE;
	if ((line - CONS_MINOR) < NR_CONS) {
		tp = tty_addr(line - CONS_MINOR);
	} else
	if (line == LOG_MINOR) {
		tp = tty_addr(0);
	} else
	if ((line - RS232_MINOR) < NR_RS_LINES) {
		tp = tty_addr(line - RS232_MINOR + NR_CONS);
	} else
	if ((line - TTYPX_MINOR) < NR_PTYS) {
		tp = tty_addr(line - TTYPX_MINOR + NR_CONS + NR_RS_LINES);
	} else
	if ((line - PTYPX_MINOR) < NR_PTYS) {
		tp = tty_addr(line - PTYPX_MINOR + NR_CONS + NR_RS_LINES);
		do_pty(tp, &tty_mess);
		continue;			/* this is a pty, not a tty */
	} else {
		tp = NULL;
	}

	/* If the device doesn't exist or is not configured return ENXIO. */
	if (tp == NULL || !tty_active(tp)) {
		tty_reply(TASK_REPLY, tty_mess.m_source,
						tty_mess.PROC_NR, ENXIO);
		continue;
	}

	/* Execute the requested function. */
	switch (tty_mess.m_type) {
	    case DEV_READ:	do_read(tp, &tty_mess);		break;
	    case DEV_WRITE:	do_write(tp, &tty_mess);	break;
	    case DEV_IOCTL:	do_ioctl(tp, &tty_mess);	break;
	    case DEV_OPEN:	do_open(tp, &tty_mess);		break;
	    case DEV_CLOSE:	do_close(tp, &tty_mess);	break;
	    case CANCEL:	do_cancel(tp, &tty_mess);	break;
	    default:		tty_reply(TASK_REPLY, tty_mess.m_source,
						tty_mess.PROC_NR, EINVAL);
	}
  }
}

	...

/*===========================================================================*
 *				mouse_interruption			     *
 *===========================================================================*/
PRIVATE void mouse_interruption(void)
{
/* Check for a mouse interruption and print cursor */

	if (mouse_status.mouse_flag)
	{
		mouse_status.mouse_flag = 0;

		/* DEBUGGING AND TESTING */
		/*printf("Bytes received: 0x%X 0x%X 0x%X\n", mouse_status.b1, mouse_status.dx, mouse_status.dy);	
		printf("X = %d\tY = %d\t", mouse_status.x, mouse_status.y);*/

		/* Checking screen limits on x coordenate */ 
		if (mouse_status.x < 0)
			mouse_status.x = 0;
		else if (mouse_status.x > 79)
			mouse_status.x = 79;

		/* Checking screen limits on y coordenate */ 
		if (mouse_status.y < 0)
			mouse_status.y = 0;
		else if (mouse_status.y > 24)
			mouse_status.y = 24;

		/* Checking left button press */
		if (mouse_status.left_button == 1)
		{
			dec_current_console();
			select_console(current_mouse_console);
			/* print_tty(current_mouse_tty, "LEFT CLICK!!!\n"); */
		}

		/* Checking right button press */
		if (mouse_status.right_button == 1)
		{
			inc_current_console();
			select_console(current_mouse_console);
			/* print_tty(current_mouse_tty, "RIGHT CLICK!!!\n"); */
		}

		/* Checking middle button press */
		/* if (mouse_status.middle_button == 1)
			print_tty(current_mouse_tty, "MIDDLE BUTTON CLICK!!!\n");*/

		/* Print mouse cursor */
		ms_cursor_print(current_mouse_tty, mouse_status.x, mouse_status.y);

		/* SCROLL MOUSE FUNCTIONALITY */
		/*if (mouse_status.y == 0)
			scroll_screen_tty(current_mouse_tty, 0);
			
		if (mouse_status.y == 24)
			scroll_screen_tty(current_mouse_tty, 1);*/
	}
}

/*===========================================================================*
 *				dec_current_console			     *
 *===========================================================================*/
PRIVATE void dec_current_console(void)
{
/* Change current console to the next one */

	if (current_mouse_console > 0)
	{
		current_mouse_console--;
		current_mouse_tty--;
	}

	return;
}

/*===========================================================================*
 *				inc_current_console			     *
 *===========================================================================*/
PRIVATE void inc_current_console(void)
{
/* Change current console to the previous one */
	
	if (current_mouse_console < NR_CONS - 1)
	{
		current_mouse_console++;
		current_mouse_tty++;
	}

	return;
}

/*===========================================================================*
 *				print_tty			     *
 *===========================================================================*/
PRIVATE void print_tty(struct tty *tp, char * s)
{
/* Print string in a given terminal */

	int i;

	for (i = 0; s[i] != '\0'; i++)
		out_char_tty(tp, s[i]);

	return;
}
